package com.sky.service.impl;

import com.alibaba.druid.sql.ast.statement.SQLAlterTableRename;
import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkSpaceService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;


import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;

import java.util.*;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private WorkSpaceService workSpaceService;


    @Override
    public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {


        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();


        List<LocalDate> dateList = getDateList(begin, end);

        String dataString = StringUtils.join(dateList, ",");

        turnoverReportVO.setDateList(dataString);
        List<String> amounts = new ArrayList<>();
        for (LocalDate date : dateList){
            String strDate = date.toString();
            Double amount = reportMapper.getTurnoverStatistics(strDate, strDate+" 23:59:59");
            amount = amount!=null?amount:0.0;
            amounts.add(amount.toString());
        }

        String amountString = String.join(",", amounts);

        turnoverReportVO.setTurnoverList(amountString);

        return turnoverReportVO;
    }

    @Override
    public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
        UserReportVO userReportVO = new UserReportVO();
        List<LocalDate> dateList = getDateList(begin, end);
        String dateString = StringUtils.join(dateList, ",");

        List<Integer> totalUsers = new ArrayList<>();
        List<Integer> newUsers = new ArrayList<>();
        // 查询用户总量
        for (LocalDate date : dateList){

            Integer userNum = reportMapper.getUserStatisticsWithDate(LocalDate.MIN, date.plusDays(1));
            userNum = userNum==null?0:userNum;
            totalUsers.add(userNum);
            Integer newUserNum = reportMapper.getUserStatisticsWithDate(date, date.plusDays(1));
            newUserNum = newUserNum==null?0:newUserNum;
            newUsers.add(newUserNum);
        }

        userReportVO.setDateList(dateString);
        userReportVO.setTotalUserList(StringUtils.join(totalUsers, ","));
        userReportVO.setNewUserList(StringUtils.join(newUsers, ","));
        return userReportVO;

    }

    @Override
    public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getDateList(begin, end);
        List<Integer> orderCountList = new ArrayList<>();
        double orderCompleteRate = 0.0;
        int totalOrderCount = 0;
        int validOrderCount = 0;
        List<Integer> validOrderCountList = new ArrayList<>();

        for (LocalDate date : dateList){
            // date日的订单总数
            orderCountList.add(reportMapper.getOrderCountByStatus(date, date.plusDays(1),null ));
            // date日的有效订单总数
            validOrderCountList.add(reportMapper.getOrderCountByStatus(date, date.plusDays(1), Orders.COMPLETED));

        }
        totalOrderCount = orderCountList.stream().mapToInt(Integer::intValue).sum();
        validOrderCount = validOrderCountList.stream().mapToInt(Integer::intValue).sum();
        if (totalOrderCount!=0){
            orderCompleteRate = (double) validOrderCount / (double) totalOrderCount;
        }
        return OrderReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .validOrderCountList(StringUtils.join(validOrderCountList, ","))
                .orderCountList(StringUtils.join(orderCountList, ","))
                .orderCompletionRate(orderCompleteRate)
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .build();
    }

    @Override
    public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) {
        if (begin.isAfter(end)) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        List<String>  names = new ArrayList<>();
        List<Integer> nums = new ArrayList<>();

        List<GoodsSalesDTO> rs = reportMapper.getTop10(begin, end);
        for (GoodsSalesDTO goodsSalesDTO : rs){
            names.add(goodsSalesDTO.getName());
            nums.add(goodsSalesDTO.getNumber());
        }

//        Map<String, Map<String, Integer>> top10 = reportMapper.getTop10(begin, end);
//        for (Map.Entry<String, Map<String, Integer>> entry : top10.entrySet()){
//            names.add(entry.getKey());
//            nums.add(entry.getValue().get("number"));
//        }



        return SalesTop10ReportVO.builder()
                .nameList(StringUtils.join(names, ","))
                .numberList(StringUtils.join(nums, ","))
                .build();
    }

    @Override
    public void exportExcel(HttpServletResponse response) {
        // 获取excel模板
        try{
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
            assert inputStream != null;
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            // 写入数据
            LocalDate begin = LocalDate.now().minusDays(30);
            LocalDate end = LocalDate.now();
            BusinessDataVO businessDataVO = workSpaceService.getBusinessData(begin, end);
            XSSFRow row = sheet.getRow(1);
            // 写入日期
            row.getCell(1).setCellValue(begin +"至"+end.minusDays(1));
            // 写入概览
            row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());
            // 写入明细
            for (int i = 0; i <30; i++) {
                businessDataVO = workSpaceService.getBusinessData(begin.plusDays(i), begin.plusDays(i+1));
                row = sheet.getRow(7+i);
                row.getCell(1).setCellValue(String.valueOf(begin.plusDays(i)));
                row.getCell(2).setCellValue(businessDataVO.getTurnover());
                row.getCell(3).setCellValue(businessDataVO.getValidOrderCount());
                row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessDataVO.getUnitPrice());
                row.getCell(6).setCellValue(businessDataVO.getNewUsers());
            }

            // 响应给浏览器
            ServletOutputStream outputStream = response.getOutputStream();

            excel.write(outputStream);
            outputStream.close();
            excel.close();
            inputStream.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    private List<LocalDate> getDateList(LocalDate begin, LocalDate end){
        if (begin.isAfter(end)) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        List<LocalDate> datelist = new ArrayList<>();
        datelist.add(begin);
        while (begin.isBefore(end)){
            begin = begin.plusDays(1);
            datelist.add(begin);
        }
        return datelist;
    }
}
